<!-- 表格 -->
<template>
	<div class="table-container">
		<div style="min-height: calc(100vh - 150px)">
			<div class="table-toolbar" v-if="hasToolbar">
				<div class="table-toolbar-left">
					<slot name="toolbarBtn"></slot>
				</div>
				<div class="table-toolbar-right flex-center">
					<template v-if="multipleSelection.length > 0">
						<el-tooltip effect="dark" content="删除选中" placement="top">
							<el-icon class="columns-setting-icon" @click="delSelection(multipleSelection)">
								<Delete />
							</el-icon>
						</el-tooltip>
						<el-divider direction="vertical" />
					</template>
					<el-tooltip effect="dark" content="刷新" placement="top">
						<el-icon class="columns-setting-icon" @click="refreshPage">
							<Refresh />
						</el-icon>
					</el-tooltip>
					<el-divider direction="vertical" />
					<el-tooltip effect="dark" content="列设置" placement="top">
						<el-dropdown :hide-on-click="false" size="small" trigger="click">
							<el-icon class="columns-setting-icon">
								<Setting />
							</el-icon>
							<template #dropdown>
								<el-dropdown-menu>
									<el-dropdown-item v-for="(c, i) in tableOption" :key="i">
										<el-checkbox v-model="c.visible" :label="c.label" />
									</el-dropdown-item>
								</el-dropdown-menu>
							</template>
						</el-dropdown>
					</el-tooltip>
				</div>
			</div>

			<el-table
				stripe
				:border="border"
				ref="tableSortRef"
				:data="tableData"
				:row-key="rowKey"
				tooltip-effect="dark"
				:height="viewportHeight"
				@header-click="headerClick"
				:show-summary="showSummary"
				:default-expand-all="false"
				@row-click="handleRowChange"
				@sort-change="tableSortChange"
				:span-method="objectSpanMethod"
				:cell-style="columnBackgroundStyle"
				@cell-dblclick="handleDoubleChange"
				:header-cell-style="headerCellStyle"
				:row-class-name="tableRowClassName"
				@selection-change="handleSelectionChange"
			>
				<!-- 复选列 -->
				<el-table-column v-if="selectionIsShow" type="selection" reserve-selection width="55" />

				<!-- 序号 -->
				<el-table-column v-if="indexIsShow" :label="$t('message.table.pageNumber')" width="90" type="index" fixed="left" />

				<template v-for="column in tableOption" :key="column.prop">
					<!-- :fixed="column.prop == 'operation' ? 'right' : ''" -->
					<el-table-column
						:prop="column.prop"
						:sortable="column.sortable"
						:label="column.label"
						:width="column.width"
						:show-overflow-tooltip="column.showTooltip"
					>
						<template #default="scope">
							<slot v-if="column.slotName" :scope="scope" :name="column.slotName"></slot>
							<div v-else>
								{{ scope.row[column.prop] }}
							</div>
						</template>
					</el-table-column>
				</template>

				<el-table-column v-if="showHandleButton" fixed="right" :label="$t('message.table.pageOperate')" :width="handleColWidth">
					<template #default="{ row }">
						<el-button v-if="showHandleEdit" type="primary" @click="handleEdit(row)" size="small"> {{ $t('message.table.pageEdit') }}</el-button>

						<el-button v-if="showHandleDelete" type="danger" @click="handleDelete(row)" size="small"> {{ $t('message.table.pageDele') }}</el-button>

						<el-button v-if="showHandleDetail" type="primary" size="small" @click="handleDetail(row)"> {{ $t('message.table.pageViews') }}</el-button>

						<slot name="customButton" :row="row"></slot>
					</template>
				</el-table-column>

				<template #empty>
					<el-empty class="vab-data-empty" description="暂无数据" />
				</template>
			</el-table>
		</div>

		<div v-show="Number(total) > 0" class="pagination">
			<!-- 分页组件删除当前页最后一条数据没有跳转到上一页显示暂无数据的问题 v-show/v-if -->
			<el-pagination
				background
				:current-page="pageNo"
				:page-size="pageSize"
				class="custom-pagination"
				:page-sizes="[10, 30, 50, 100]"
				:total="Number(total)"
				layout="total, sizes, prev, pager, next, jumper"
				@current-change="handleCurrentChange"
				@size-change="handleSizeChange"
			/>
		</div>

		<div style="height: 10px"></div>
	</div>
</template>

<script lang="ts">
import { PropType, defineComponent, ref, CSSProperties, onMounted, onUnmounted } from 'vue';
import { Delete, Edit, View, Refresh, Setting } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';

interface tableOption {
	prop: string;
	label: string;
	width?: number;
	sortable?: boolean;
	visible?: boolean;
	slotName?: string;
	showTooltip?: boolean;
}

export default defineComponent({
	name: 'tableCustom',
	props: {
		height: {
			type: Number,
			default: 600,
		}, //表格高度

		selectionIsShow: {
			type: Boolean,
			default: false,
		}, // 是否显示多选列

		indexIsShow: {
			type: Boolean,
			default: false,
		}, // 是否显示索引列

		showHandleButton: {
			type: Boolean,
			default: false,
		}, // 是否显示操作列

		handleColWidth: {
			type: Number,
			default: 255,
		}, // 操作列列宽

		tableOption: {
			type: Array as PropType<tableOption[]>,
			default: () => {
				return [];
			},
		}, // 表头

		tableData: {
			type: Array,
			default: () => {
				return [];
			},
		}, // 表格数据

		showHandleEdit: {
			type: Boolean,
			default: false,
		}, // 编辑按钮

		showHandleDelete: {
			type: Boolean,
			default: false,
		}, // 删除按钮

		rowKey: {
			type: String,
			default: 'id',
		},

		hasToolbar: {
			type: Boolean,
			default: true,
		}, // 是否显示工具栏

		total: {
			type: [String, Number],
			default: 0,
		}, // 数据总条数

		layout: {
			type: String,
			default: 'total, prev, pager, next',
		}, // 分页布局

		delSelection: {
			type: Function,
			default: () => {},
		}, // 删除多选数据

		refresh: {
			type: Function,
			default: () => {},
		}, // 是否刷新

		supportMergeColumns: {
			type: Boolean,
			default: false,
		}, // 是否合并列

		showSummary: {
			type: Boolean,
			default: false,
		}, // 是否显示合计

		mergeColumnsArr: {
			type: Array,
			default: () => {
				return [];
			},
		}, // 合并列数据

		showHandleDetail: {
			type: Boolean,
			default: false,
		}, // 详情按钮

		border: { type: Boolean, default: false }, // 表格是否展示边框

		currentPage: {
			type: Number,
			default: 1,
		},

		pageSize: {
			type: Number,
			default: 10,
		},
	},
	setup(props, { emit }) {
		const pageNo = ref(1);
		const pageSize = ref(10);
		const tableSortRef = ref(null);

		// 详情
		const handleDetail = (row: any) => {
			emit('handleDetail', row);
		};

		// 编辑
		const handleEdit = (row: any) => {
			emit('handleEdit', row);
		};

		const multipleSelection = ref<any[]>([]);
		// 多选
		const handleSelectionChange = (selection: any[]) => {
			multipleSelection.value = selection;
			emit('handleSelectionChange', selection);
		};

		// 页面展示第几页
		const handleCurrentChange = (val: number) => {
			pageNo.value = val;
			emit('handleCurrentChange', val);
		};

		// 每页展示条数
		const handleSizeChange = (val: number) => {
			pageSize.value = val;
			emit('handleSizeChange', val);
		};

		// 定义排序变更事件的参数类型
		interface SortChangeEvent {
			prop: string | null; // 排序字段
			order: string | null; // 排序顺序（如 'ascending' 或 'descending'）
		}

		// 修改 tableSortChange 方法，添加类型声明
		const tableSortChange = ({ prop, order }: SortChangeEvent) => {
			// 根据排序字段和排序方式,重新获取数据并更新 tableData
			emit('tableSortChange', { prop, order });
		};

		// 定义 columnBackgroundStyle 函数的参数类型
		interface ColumnCellStyleParams {
			row: any; // 表格行数据
			column: any; // 表格列配置
			rowIndex: number; // 行索引
			columnIndex: number; // 列索引
		}

		// 显示蓝色
		const columnBackgroundStyle = ({ row, column, rowIndex, columnIndex }: ColumnCellStyleParams): CSSProperties => {
			if (column.label == '端口') {
				// 让下标为1的列数背景颜色显示为蓝色（颜色自定义根据需求来）
				return {
					color: 'blue',
					cursor: 'pointer',
					'text-decoration': 'underline',
				};
			} else {
				return {
					'text-align': 'center',
				};
			}
		};

		// 定义 objectSpanMethod 参数的类型
		interface ObjectSpanMethodParams {
			row: any; // 表格行数据
			rowIndex: number; // 行索引
			column: any; // 表格列配置
			columnIndex: number; // 列索引
		}

		// 合并列
		const objectSpanMethod = ({ row, rowIndex, column, columnIndex }: ObjectSpanMethodParams) => {
			if (!props.supportMergeColumns) return { rowspan: 1, colspan: 1 };
			if (columnIndex === 0) {
				// 二维数组存储的数据 取出
				const _row = props.mergeColumnsArr[rowIndex];
				if (typeof _row === 'number') {
					const _col = _row > 0 ? 1 : 0;
					return {
						rowspan: _row,
						colspan: _col,
					};
				}
			}
			return { rowspan: 1, colspan: 1 };
		};

		//删除
		const handleDelete = (row: any) => {
			ElMessageBox.confirm('你确定要删除当前项吗?', '警告', {
				confirmButtonText: '确定',
				cancelButtonText: '取消',
				type: 'warning',
			})
				.then(() => {
					emit('handleDelete', row);
				})
				.catch(() => {
					ElMessage({
						type: 'info',
						message: '操作取消',
					});
				});
		};

		// 表头样式
		const headerCellStyle = ({
			row,
			column,
			rowIndex,
			columnIndex,
		}: {
			row: any;
			column: any;
			rowIndex: number;
			columnIndex: number;
		}): CSSProperties => {
			return {
				backgroundColor: '#0E244B',
				color: '#fff',
				fontSize: '1rem',
				fontWeight: 'bold',
				borderBottom: '1px solid #2d4a7a',
				textAlign: 'center' as CSSProperties['textAlign'],
			};
		};

		// 刷新
		const refreshPage = () => {
			emit('refresh');
		};

		// 表头被点击
		const headerClick = (column: any) => {
			emit('headerClick', column.property);
		};

		//一行被点击
		const handleRowChange = (val: any) => {
			emit('handleRowChange', val);
		};

		//双击
		const handleDoubleChange = (val: any) => {
			emit('handleDoubleChange', val);
		};

		// 定义 tableRowClassName 参数的类型
		interface TableRowClassNameParams {
			row: any; // 表格行数据
			rowIndex: number; // 行索引
		}

		// 表格行样式
		const tableRowClassName = ({ row, rowIndex }: TableRowClassNameParams) => {
			if (rowIndex % 2 == 0) {
				return 'first-row';
			} else {
				return 'second-row';
			}
		};

		const viewportHeight = ref(0);

		const handleResize = () => {
			// 计算可视区域高度 - 其他固定元素高度（如分页、表头等）
			const pagePadding = 150; // 页面上下边距
			const paginationHeight = 150; // 分页组件高度
			const tableHeaderHeight = 150; // 表头高度

			viewportHeight.value = window.innerHeight - pagePadding - paginationHeight - tableHeaderHeight - 190;

			// 最小高度保护
			viewportHeight.value = Math.max(viewportHeight.value, 300);
		};

		onMounted(() => {
			handleResize();
			window.addEventListener('resize', handleResize);
		});

		onUnmounted(() => {
			window.removeEventListener('resize', handleResize);
		});

		return {
			Edit,
			View,
			Delete,
			Refresh,
			pageNo,
			Setting,
			pageSize,
			handleEdit,
			headerClick,
			refreshPage,
			tableSortRef,
			handleDelete,
			handleDetail,
			viewportHeight,
			handleRowChange,
			headerCellStyle,
			tableSortChange,
			objectSpanMethod,
			handleSizeChange,
			tableRowClassName,
			multipleSelection,
			handleDoubleChange,
			handleCurrentChange,
			handleSelectionChange,
			columnBackgroundStyle,
		};
	},
});
</script>

<style lang="scss">
.table-container {
	.table-toolbar {
		display: flex;
		justify-content: space-between;
		align-items: flex-end;
		margin-bottom: 10px;
	}

	.el-table__inner-wrapper:before {
		background-color: #2d4a7a !important;
	}

	.el-table .el-table__cell {
		padding: 3px 0;
	}

	.first-row {
		color: #fff;
		font-weight: bold;
		background-color: #243957 !important;
	}

	.second-row {
		color: #fff;
		font-weight: bold;
		background-color: #0f2547 !important;
	}

	.el-scrollbar__view {
		width: 100% !important;
		height: 100% !important;
		background-color: #041424;
	}

	.el-table__body {
		width: 100% !important;
		tr {
			td {
				border-bottom: 1px solid #2d4a7a; /* 行底部边框颜色 */
			}
		}
	}

	/* 设置行悬停颜色 */
	.el-table__body tr:hover > td {
		background-color: rgba(95, 207, 250, 0.1) !important;
	}

	/* 设置行点击后的颜色 */
	.el-table__body tr.current-row > td {
		background-color: rgba(95, 207, 250, 0.2) !important;
	}

	.pagination {
		left: 0;
		bottom: 0;
		display: flex;
		position: sticky;
		margin-top: 10px;
		margin-right: 10px;
		justify-content: right !important;
	}

	.columns-setting-icon {
		font-size: 18px;
		cursor: pointer;
		color: #676767;
	}

	.table-header .cell {
		color: #333;
	}
}
</style>

<style lang="scss" scoped>
/* 使用深度选择器穿透 scoped */
:deep(.el-table) {
	/* 奇数行 */
	.first-row {
		background-color: #243957 !important;

		&:hover > td {
			background-color: rgba(95, 207, 250, 0.1) !important;
		}
	}

	/* 偶数行 */
	.second-row {
		background-color: #0f2547 !important;

		&:hover > td {
			background-color: rgba(95, 207, 250, 0.1) !important;
		}
	}

	/* 确保单元格继承行背景色 */
	.el-table__body tr td {
		background-color: inherit !important;
	}

	/* 分页样式 */
	.el-pagination {
		--el-pagination-bg-color: #0a1a32 !important;
		--el-pagination-text-color: #fff !important;
	}
}

/* 表格容器背景 */
.table-container {
	background-color: #0a1a32 !important;
}

/* 使用深度选择器穿透 */
:deep(.custom-pagination) {
	/* 整体样式 */
	.btn-prev,
	.btn-next,
	.number,
	.more {
		background: #0a1a32 !important;
		border: 1px solid #2d4a7a !important;
		color: #fff !important;
	}

	.el-input__wrapper {
		background: #0a1a32 !important;
		box-shadow: 0 0 0 1px #2d4a7a !important;
	}

	.el-select__wrapper {
		background: #0a1a32 !important;
		box-shadow: 0 0 0 1px #2d4a7a;
	}

	.el-pager {
		background-color: #2d4a7a !important;
	}

	.el-pagination.is-background .el-pager li.is-active {
		background: #2d4a7a !important;
		color: #fff !important;
	}

	/* 当前选中页 */
	.number.is-active {
		background: #2d4a7a !important;
		color: #fff !important;
		border-color: #2d4a7a !important;
	}

	/* 悬停效果 */
	.btn-prev:hover,
	.btn-next:hover,
	.number:hover {
		color: #fff !important;
		border-color: #5fcffa !important;
	}

	/* 禁用状态 */
	.btn-prev.is-disabled,
	.btn-next.is-disabled {
		color: #fff !important;
	}

	/* 文字颜色 */
	.el-pagination__total,
	.el-pagination__jump {
		color: #fff !important;
	}

	/* 下拉框样式 */
	.el-pagination__sizes .el-input__inner {
		background: #0a1a32;
		border-color: #2d4a7a;
		color: #fff;
	}
}
</style>
